﻿namespace BlogsAPI.Rdf
{
    using System.Xml.Serialization;

    /// <summary>
    /// foaf:Person
    /// The foaf:Person class represents people. 
    /// Something is a foaf:Person if it is a person. 
    /// We don't nitpic about whether they're alive, dead, real, or imaginary. 
    /// The foaf:Person class is a sub-class of the foaf:Agent class, 
    /// since all people are considered 'agents' in FOAF.
    /// </summary>
    [XmlRoot(ElementName = "Person", Namespace = "http://xmlns.com/foaf/0.1/")]
    public class FoafPerson : FoafAgent
    {
        #region foaf:Person.Core

        /// <summary>
        /// See the Code of the Geeks specification for details of the code, which provides a somewhat frivolous and willfully obscure mechanism for characterising technical expertise, interests and habits. The foaf:geekcode property is not bound to any particular version of the code. The last published version of the code was v3.12 in March 1996. 
        /// As the Geek Code website notes, the code played a small (but amusing) part in the history of the Internet. The foaf:geekcode property exists in acknowledgement of this history. It'll never be 1996 again. 
        /// The Geek Code is a densely packed collections of claims about the person it applies to; to express these claims explicitly in RDF/XML would be incredibly verbose. The syntax of the Geek Code allows for '<' and '>' characters, which have special meaning in RDF/XML. Consequently these should be carefully escaped in markup.
        /// </summary>
        /// <example><foaf:geekcode> GED/J d-- s:++&gt;: a-- C++(++++) ULU++ P+ L++ E---- W+(-) N+++ o+ K+++ w--- O- M+ V-- PS++&gt;$ PE++&gt;$ Y++ PGP++ t- 5+++ X++ R+++&gt;$ tv+ b+ DI+++ D+++ G++++ e++ h r-- y++** </foaf:geekcode></example>
        /// <value>The Code of the Geeks.</value>
        [XmlElement("geekcode", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string GeekCode { get; set; }

        /// <summary>
        /// The foaf:workInfoHomepage of a foaf:Person is a foaf:Document that describes their work. 
        /// It is generally (but not necessarily) a different document from their foaf:homepage, 
        /// and from any foaf:workplaceHomepage(s) they may have. 
        /// The purpose of this property is to distinguish those pages you often see, which describe someone's 
        /// professional role within an organisation or project. These aren't really homepages, 
        /// although they share some characterstics.
        /// </summary>
        /// <value>A work info homepage of some person; a page about their work for some organization.</value>
        [XmlElement("workInfoHomepage", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement WorkInfoHomepage { get; set; }


        /// <summary>
        /// By directly relating people to the homepages of their workplace, 
        /// we have a simple convention that takes advantage of a set of widely known identifiers,
        /// while taking care not to confuse the things those identifiers identify (ie. organizational homepages) 
        /// with the actual organizations those homepages describe.
        /// </summary>
        /// <value>A workplace homepage of some person; the homepage of an organization they work for.</value>
        [XmlElement("workplaceHomepage", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement WorkPlaceHomepage { get; set; }

        /// <summary>
        /// A foaf:currentProject relates a foaf:Person to a foaf:Document indicating some collaborative or 
        /// individual undertaking. This relationship indicates that the foaf:Person has some active role 
        /// in the project, such as development, coordination, or support.
        /// When a foaf:Person is no longer involved with a project, or perhaps is inactive for some time, 
        /// the relationship becomes a foaf:pastProject.
        /// If the foaf:Person has stopped working on a project because it has been completed 
        /// (successfully or otherwise), foaf:pastProject is applicable. In general, foaf:currentProject 
        /// is used to indicate someone's current efforts (and implied interests, concerns etc.), 
        /// while foaf:pastProject describes what they've previously been doing.
        /// </summary>
        /// <value>A current project this person works on.</value>
        [XmlElement("currentProject", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement[] CurrentProjects { get; set; }

        /// <summary>
        /// A number of naming constructs are under development to provide naming substructure; draft properties include foaf:firstName, foaf:givenname, and foaf:surname. These are not currently stable or consistent; see the issue tracker for design discussions, status and ongoing work on rationalising the FOAF naming machinery. 
        /// There is also a simple foaf:name property.
        /// </summary>
        /// <value>The first name of a person.</value>
        [XmlElement("firstName", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string FirstName { get; set; }

        /// <summary>
        /// A number of naming constructs are under development to provide naming substructure; draft properties include foaf:firstName, foaf:givenname, and foaf:surname. These are not currently stable or consistent; see the issue tracker for design discussions, status and ongoing work on rationalising the FOAF naming machinery. 
        /// There is also a simple foaf:name property.
        /// </summary>
        /// <value>The surname of some person.</value>
        [XmlElement("surname", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string Surname { get; set; }

        /// <summary>
        /// A number of naming constructs are under development to provide naming substructure; draft properties include foaf:firstName, foaf:givenname, and foaf:surname. These are not currently stable or consistent; see the issue tracker for design discussions, status and ongoing work on rationalising the FOAF naming machinery. 
        /// There is also a simple foaf:name property.
        /// </summary>
        /// <value>The family_name of some person.</value>
        [XmlElement("family_name", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string FamilyName { get; set; }


        /// <summary>
        /// Old version of foaf:img
        /// </summary>
        [XmlElement("depiction", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement Depiction
        {
            get { return Images == null || Images.Length == 0 ? null : Images[0]; } 
            set
            {
                if (Images == null || Images.Length==0)
                {
                    Images = new[] {value};
                }else
                {
                    Images[0] = value;
                }
            }
        }

        #endregion

        #region staff for parsing LJ's FOAF: @livejournal.com

        /// <summary>
        /// Title of LJ blog
        /// </summary>
        [XmlElement("journaltitle", Namespace = "http://www.livejournal.org/rss/lj/1.0/")]
        public string JournalTitle { get; set; }

        /// <summary>
        /// SubTitle of LJ blog
        /// </summary>
        [XmlElement("journalsubtitle", Namespace = "http://www.livejournal.org/rss/lj/1.0/")]
        public string JournalSubTitle { get; set; }

        #endregion

        #region useless fields by Yandex

        /// <summary>
        /// Copy of foaf:FirstName
        /// </summary>
        /// <value>имя (в отличие от фамилии)</value>
        [XmlElement("firstName", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string ya_firstName
        {
            get
            {
                return FirstName;
            }
            set
            {
                FirstName = value;
            }
        }

        /// <summary>
        /// Copy of foaf:Surname
        /// </summary>
        /// <value>отчество</value>
        [XmlElement("middleName", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string ya_middleName
        {
            get
            {
                return Surname;
            }
            set
            {
                Surname = value;
            }
        }

        /// <summary>
        /// Copy of foaf:family_name
        /// </summary>
        /// <value>отчество</value>
        [XmlElement("secondName", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string ya_family_name
        {
            get
            {
                return FamilyName;
            }
            set
            {
                FamilyName = value;
            }
        }


        #endregion

        #region usefull fields by Yandex


        /// <summary>
        /// Свойство ya:height содержит информацию о росте человека. Ростом может быть не только число, но и диапазон значений. Рост указывается в сантиметрах.
        /// </summary>
        /// <example><ya:height>190-210</ya:height></example>
        [XmlElement("height", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string Height { get; set; }

        /// <summary>
        /// Свойство ya:weight содержит информацию о весе человека. Весом может быть не только число, но и диапазон значений. Вес указывается в килограммах.
        /// </summary>
        /// <example><ya:weight>80-100</ya:weight></example>
        [XmlElement("weight", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string Weight { get; set; }

        /// <summary>
        /// Свойство ya:school содержит информацию о школе, в которой учился человек. 
        /// Понятие "школа" может трактоваться в широком смысле и означать любое образовательное учреждение.
        /// </summary>
        /// <example><ya:school rdf:resource="http://link-to-filter-by-school" ya:dateStart="2003-09" ya:dateFinish="2007-12" dc:title="Санкт-Петербургский Государственный Политехнический Университет"/></example>
        [XmlElement("school", Namespace = "http://blogs.yandex.ru/schema/foaf/")] 
        public YaSchool[] Schools { get; set; }

        #endregion

        #region some crap from LJ's foaf

        /// <summary>
        /// A number of naming constructs are under development to provide naming substructure; 
        /// draft properties include foaf:firstName, foaf:givenname, and foaf:surname. These are not currently stable or consistent; 
        /// see the issue tracker for design discussions, status and ongoing work on rationalising the FOAF naming machinery.
        /// </summary>
        /// <value>The given name of some person.</value>
        /// <remarks>There is also a simple foaf:name property.</remarks>
        [XmlElement("givenname", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string GivenName
        {
            get { return Name; }
            set { Name = value; }
        }

        /// <summary>
        /// Undescribed tag
        /// </summary>
        [XmlElement("member_name", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string MemberName
        {
            get { return Name; }
            set { Name = value; }
        }


        /// <summary>
        /// Undescribed tag
        /// </summary>
        [XmlElement("tagLine", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string TagLine
        {
            get { return JournalTitle; }
            set { JournalTitle = value; }
        }

        /// <summary>
        /// Undescribed tag
        /// </summary>
        [XmlElement("image", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string Image
        {
            get {
                return Images == null || Images.Length == 0 ? null:Images[0].Resource; 
            }
            set
            {
                if(Images == null)
                {
                    Images = new[]
                                 {
                                     new RdfElement()
                                 };
                }
                Images[0].Resource = value;
            }
        }

        #endregion
    }
}
